import { player } from '../js/player.js'
import { asteroid } from '../js/asteroid.js'
import { enemy, enemyBullet } from '../js/enemy.js'
import { bullet } from '../js/bullet.js'
import { friendly } from '../js/friendly.js'
import { meteorite } from '../js/meteorite.js'
import { fuel } from '../js/fuel.js'

class gameBoard {
  constructor() {
    this.canvas = $("canvas");
    this.ctx = this.canvas.getContext('2d');
    this.bgSpeed = 0
    this.asteroidIndex = 0
    this.enemyIndex = 0
    this.friendlyIndex = 0
    this.meteoriteIndex = 0
    this.fuelIndex = 0
    this.id = 0
    this.enemyId = 0
    this.bulletsId = 0
    this.friendlyId = 0
    this.meteoriteId = 0
    this.enemyBulletId = 0
    this.fuelId = 0
    this.bullets = {}
    this.asteroidObj = {}
    this.enemyObj = {}
    this.friendlyObj = {}
    this.meteoriteObj = {}
    this.enemybulletObj = {}
    this.fuelObj = {}
    this.space = true
    this.timers = null
    this.timeNum = 0
    this.timeIndex = 0
    this.fraction = 0
    this.suspend = false
    this.music = true
    this.end = true
    this.obj = {}
    this.arr = []
    this.date = localStorage.getItem("value") === null ? [] : JSON.parse(localStorage.getItem('value'))
    this.start()
  }
  $(dom) {
    return document.querySelector(dom)
  }
  $all(dom) {
    return document.querySelectorAll(dom)
  }
  start() {
    // 开始按钮
    this.$('.start').addEventListener('click', () => {
      this.gameStart()
      this.controllerKey()
      this.$("#background").play()
      this.$(".gameStart").style.opacity = "0"
      this.$(".gameStart").style.display = "none"
      this.$('.gameInfo').style.opacity = "1"
      this.$('.controller_box').style.opacity = '1'

      // 增大字体
      this.$(".maxSize").addEventListener('click', () => {
        if (this.end) {
          this.fontSize = Number(getComputedStyle(this.$('html'), null)['fontSize'].substring(0, getComputedStyle(this.$('html'), null)['fontSize'].length - 2))
          this.fontSize += 1
          this.$("html").style.fontSize = this.fontSize + 'px'
        }
      })
      // 减小字体
      this.$(".minSize").addEventListener('click', () => {
        if (this.end) {
          this.fontSize = Number(getComputedStyle(this.$('html'), null)['fontSize'].substring(0, getComputedStyle(this.$('html'), null)['fontSize'].length - 2))
          this.fontSize -= 1
          this.$("html").style.fontSize = this.fontSize + 'px'
        }
      })
      // 暂停音乐
      this.$(".pause_music").addEventListener('click', () => {
        this.music = !this.music
        if (this.music && this.end) {
          this.$("#background").play()
          this.$(".pause_music img").src = "./images/音乐.png"
        } else {
          this.$("#background").pause()
          this.$(".pause_music img").src = "./images/静音.png"
        }
      })
      // 暂停游戏
      this.$(".pause_game").addEventListener('click', () => {
        this.pause_games()
      })
    })
  }
  controllerKey() {
    this.$all(".controller_item img").forEach(item => {
      item.addEventListener('mouseover', (e) => {
        let index = e.target.getAttribute('index')
        if (index == 'top') {
          this.player.move('up')
        } else if (index == 'right') {
          this.player.move('right')
        } else if (index == 'left') {
          this.player.move('left')
        } else if (index == 'bottom') {
          this.player.move('down')
        }
      })
      item.addEventListener('mouseout', (e) => {
        let index = e.target.getAttribute('index')
        if (index == 'top') {
          this.player.unset_move('up')
        } else if (index == 'right') {
          this.player.unset_move('right')
        } else if (index == 'left') {
          this.player.unset_move('left')
        } else if (index == 'bottom') {
          this.player.unset_move('down')
        }
      })
    })
  }
  //  暂停游戏
  pause_games() {
    if (this.end) {
      this.suspend = !this.suspend
      if (this.suspend) {
        this.music = false
        cancelAnimationFrame(this.timers)
        this.$(".pause_music img").src = "./images/静音.png"
        $(".pause_game img").src = "./images/暂停.png"
        this.$("#background").pause()
        if (this.enemybulletObj[this.enemyBulletId]) {
          this.enemybulletObj[this.enemyBulletId].suspend()
        }
        this.player.suspend()
        if (this.bullets[this.bulletsId]) {
          this.bullets[this.bulletsId].suspend()
        }
      } else {
        this.music = true
        this.franme()
        this.$(".pause_music img").src = "./images/音乐.png"
        $(".pause_game img").src = "./images/继续.png"
        this.$("#background").play()
        if (this.enemybulletObj[this.enemyBulletId]) {
          this.enemybulletObj[this.enemyBulletId].frame()
        }
        this.player.frame()
        if (this.bullets[this.bulletsId]) {
          this.bullets[this.bulletsId].frame()
        }
      }
    }
  }
  // 键盘事件
  keyMove() {
    if (this.end) {
      document.addEventListener('keydown', (e) => {
        if (e.key == "ArrowUp") {
          this.player.move('up')
        } else if (e.key == "ArrowLeft") {
          this.player.move('left')
        } else if (e.key == "ArrowRight") {
          this.player.move('right')
        } else if (e.key == "ArrowDown") {
          this.player.move('down')
        } else if (e.key == " ") {
          if (this.space && !this.suspend) {
            this.space = false
            this.bulletsId++
            this.bullets[this.bulletsId] = new bullet(this, this.player)
            if (this.music) this.$("#shoot").play()
          }
        } else if (e.key == "p") this.pause_games()
      })

      document.addEventListener('keyup', (e) => {
        if (e.key == "ArrowUp") {
          this.player.unset_move('up')
        } else if (e.key == "ArrowLeft") {
          this.player.unset_move('left')
        } else if (e.key == "ArrowRight") {
          this.player.unset_move('right')
        } else if (e.key == "ArrowDown") {
          this.player.unset_move('down')
        } else if (e.key == " ") {
          this.space = true
        }
      })
    }
  }
  // 功能初始化
  gameStart() {
    this.franme()
    this.keyMove()
    this.player = new player(this)
  }
  // 进入排行榜
  ranking() {
    this.$(".submit").addEventListener('click', () => {
      if (this.$(".userName").value !== '') {
        this.$(".infoTable").style.transform = "translate(-50%, -50%) scale(0)"
        this.$(".ranking").style.transform = "translate(-50%, -50%) scale(1)"
        this.userName = this.$(".userName").value
        this.obj['name'] = this.userName
        this.obj['score'] = this.fraction
        this.obj['time'] = this.timeNum
        if (this.date !== []) {
          this.date.push(this.obj)
          localStorage.setItem('value', JSON.stringify(this.date))
        } else {
          this.arr.push(this.obj)
          localStorage.setItem('value', JSON.stringify(this.arr))
        }
        this.rankingInfo()
      } else {
        this.$(".userName").classList.add("red")
      }
    })
  }
  // 排行榜信息
  rankingInfo() {
    if (this.date !== []) {
      this.$(".tbody").innerHTML = ''
      this.date.sort((a, b) => {
        return b.score - a.score ? b.score - a.score : a.time - b.time && a.score == b.score ? b.time - a.time : a.time - b.time
      })
      let num = 1
      this.date.forEach((item, index) => {
        let res = 1
        if (this.date[index].score == this.date[index - 1]?.score && this.date[index].time == this.date[index - 1]?.time) {
          res = num
        } else {
          res = num = index + 1
        }
        this.$(".tbody").innerHTML += `
          <tr>
            <td>${res}</td>
            <td>${item.name}</td>
            <td>${item.score}</td>
            <td>${item.time}</td>
          </tr>
        `
      });
    }
    this.$(".restart").addEventListener('click', () => {
      location.reload()
    })
  }
  // 计时
  time() {
    this.timeIndex++
    if (this.timeIndex % 60 === 0) {
      this.timeNum += 1
      this.timeWidth = Number(getComputedStyle(this.$(".progress"), null)['width'].substring(0, getComputedStyle(this.$(".progress"), null)['width'].length - 2))
      this.timeWidth -= 3.33
      this.$(".fuelCounter span").innerHTML = Math.floor(this.timeWidth / 3.33) < 1 ? 0 : Math.floor(this.timeWidth / 3.33)
      this.$(".progress").style.width = this.timeWidth + 'px'
      this.$(".time").innerHTML = `${this.timeNum}秒`
      if (this.timeWidth < 0) {
        this.$(".infoTable").style.transform = "translate(-50%, -50%) scale(1.5)"
        this.pause_games()
        this.ranking()
        this.end = false
      }
    }
  }
  // 燃料减少
  reduce() {
    this.timeWidth = Number(getComputedStyle(this.$(".progress"), null)['width'].substring(0, getComputedStyle(this.$(".progress"), null)['width'].length - 2))
    if (this.timeWidth < 50) {
      this.timeWidth = 0
      this.$(".fuelCounter span").innerHTML = 0
    } else {
      this.timeWidth -= 50
    }
    this.$(".progress").style.width = this.timeWidth + 'px'
    this.$(".fuelCounter span").innerHTML = Math.floor(this.timeWidth / 3.33) < 1 ? 0 : Math.floor(this.timeWidth / 3.33)
  }
  // 碰撞检测
  collision() {
    // 子弹的位置
    for (let key in this.bullets) {
      this.bulletsOffsetTop = this.bullets[key].y
      this.bulletsOffsetLeft = this.bullets[key].positionX
      this.bulletsOffsetRight = this.bullets[key].positionX + this.bullets[key].width
      this.bulletsOffsetBottom = this.bullets[key].y + this.bullets[key].height
      // 敌机的位置
      for (let key in this.enemyObj) {
        this.enemyObjOffsetTop = this.enemyObj[key].randomY
        this.enemyObjOffsetLeft = this.enemyObj[key].x
        this.enemyObjOffsetRight = this.enemyObj[key].x + this.enemyObj[key].width
        this.enemyObjOffsetBottom = this.enemyObj[key].randomY + this.enemyObj[key].height
        // 子弹&敌机
        if (this.bulletsOffsetLeft < this.enemyObjOffsetRight && this.bulletsOffsetRight > this.enemyObjOffsetLeft &&
          this.bulletsOffsetBottom > this.enemyObjOffsetTop && this.bulletsOffsetTop < this.enemyObjOffsetBottom) {
          delete this.enemyObj[key]
          if (this.bullets[this.bulletsId]) {
            this.bullets[this.bulletsId].delete()
          }
          this.fraction += 5
          this.$(".score").innerHTML = `${this.fraction}分`
          if (this.music) this.$("#destroyed").play()
        }
      }
      // 友机的位置
      for (let key in this.friendlyObj) {
        this.friendlyObjOffsetTop = this.friendlyObj[key].randomY
        this.friendlyObjOffsetLeft = this.friendlyObj[key].x
        this.friendlyObjOffsetRight = this.friendlyObj[key].x + this.friendlyObj[key].width
        this.friendlyObjOffsetBottom = this.friendlyObj[key].randomY + this.friendlyObj[key].height
        // 子弹&友机
        if (this.bulletsOffsetLeft < this.friendlyObjOffsetRight && this.bulletsOffsetRight > this.friendlyObjOffsetLeft &&
          this.bulletsOffsetBottom > this.friendlyObjOffsetTop && this.bulletsOffsetTop < this.friendlyObjOffsetBottom) {
          delete this.friendlyObj[key]
          if (this.bullets[this.bulletsId]) {
            this.bullets[this.bulletsId].delete()
          }
          this.fraction -= 10
          this.$(".score").innerHTML = `${this.fraction}分`
        }
      }
      // 陨石的位置
      for (let key in this.meteoriteObj) {
        this.meteoriteObjOffsetTop = this.meteoriteObj[key].randomY - 50
        this.meteoriteObjOffsetLeft = this.meteoriteObj[key].positionX
        this.meteoriteObjOffsetRight = this.meteoriteObj[key].positionX + this.meteoriteObj[key].width
        this.meteoriteObjOffsetBottom = this.meteoriteObj[key].randomY - 50 + this.meteoriteObj[key].height
        // 子弹&陨石
        if (this.bulletsOffsetLeft < this.meteoriteObjOffsetRight && this.bulletsOffsetRight > this.meteoriteObjOffsetLeft &&
          this.bulletsOffsetBottom > this.meteoriteObjOffsetTop && this.bulletsOffsetTop < this.meteoriteObjOffsetBottom) {
          // 删除陨石
          if (this.meteoriteObj[this.meteoriteId].hp >= 2) {
            delete this.meteoriteObj[key]
            this.fraction += 10
            this.$(".score").innerHTML = `${this.fraction}分`
            if (this.music) this.$("#destroyed").play()
          } else {
            this.meteoriteObj[this.meteoriteId].hp += 1
          }
          // 删除子弹
          if (this.bullets[this.bulletsId]) {
            this.bullets[this.bulletsId].delete()
          }
        }
      }
    }
    // 主机的位置
    if (this.player) {
      this.playerOffsetTop = this.player.y
      this.playerOffsetLeft = this.player.x
      this.playerOffsetRight = this.player.x + this.player.width
      this.playerOffsetBottom = this.player.y + this.player.height
      // 敌机的位置
      for (let key in this.enemyObj) {
        this.enemyObjOffsetTop = this.enemyObj[key].randomY
        this.enemyObjOffsetLeft = this.enemyObj[key].x
        this.enemyObjOffsetRight = this.enemyObj[key].x + this.enemyObj[key].width
        this.enemyObjOffsetBottom = this.enemyObj[key].randomY + this.enemyObj[key].height
        // 主机&敌机
        if (this.playerOffsetLeft < this.enemyObjOffsetRight && this.playerOffsetRight > this.enemyObjOffsetLeft &&
          this.playerOffsetBottom > this.enemyObjOffsetTop && this.playerOffsetTop < this.enemyObjOffsetBottom) {
          delete this.enemyObj[key]
          this.reduce()
        }
      }
      // 友机的位置
      for (let key in this.friendlyObj) {
        this.friendlyObjOffsetTop = this.friendlyObj[key].randomY
        this.friendlyObjOffsetLeft = this.friendlyObj[key].x
        this.friendlyObjOffsetRight = this.friendlyObj[key].x + this.friendlyObj[key].width
        this.friendlyObjOffsetBottom = this.friendlyObj[key].randomY + this.friendlyObj[key].height
        // 主机&友机
        if (this.playerOffsetLeft < this.friendlyObjOffsetRight && this.playerOffsetRight > this.friendlyObjOffsetLeft &&
          this.playerOffsetBottom > this.friendlyObjOffsetTop && this.playerOffsetTop < this.friendlyObjOffsetBottom) {
          delete this.friendlyObj[key]
          this.reduce()
        }
      }
      // 陨石的位置
      for (let key in this.meteoriteObj) {
        this.meteoriteObjOffsetTop = this.meteoriteObj[key].randomY
        this.meteoriteObjOffsetLeft = this.meteoriteObj[key].positionX
        this.meteoriteObjOffsetRight = this.meteoriteObj[key].positionX + this.meteoriteObj[key].width
        this.meteoriteObjOffsetBottom = this.meteoriteObj[key].randomY + this.meteoriteObj[key].height
        // 敌机&陨石
        if (this.playerOffsetLeft < this.meteoriteObjOffsetRight && this.playerOffsetRight > this.meteoriteObjOffsetLeft &&
          this.playerOffsetBottom > this.meteoriteObjOffsetTop && this.playerOffsetTop < this.meteoriteObjOffsetBottom) {
          delete this.meteoriteObj[key]
          this.reduce()
        }
      }
      // 燃料的位置
      for (let key in this.fuelObj) {
        this.fuelObjOffsetTop = this.fuelObj[key].y
        this.fuelObjOffsetLeft = this.fuelObj[key].randomX
        this.fuelObjOffsetRight = this.fuelObj[key].randomX + this.fuelObj[key].width
        this.fuelObjOffsetBottom = this.fuelObj[key].y + this.fuelObj[key].height
        // 主机&燃料
        if (this.playerOffsetLeft < this.fuelObjOffsetRight && this.playerOffsetRight > this.fuelObjOffsetLeft &&
          this.playerOffsetBottom > this.fuelObjOffsetTop && this.playerOffsetTop < this.fuelObjOffsetBottom) {
          delete this.fuelObj[key]
          this.timeWidth = Number(getComputedStyle(this.$(".progress"), null)['width'].substring(0, getComputedStyle(this.$(".progress"), null)['width'].length - 2))
          if (this.timeWidth > 50) {
            this.timeWidth = 100
            this.$(".fuelCounter span").innerHTML = 30
          } else {
            this.timeWidth += 50
          }
          this.$(".progress").style.width = this.timeWidth + 'px'
          this.$(".fuelCounter span").innerHTML = Math.floor(this.timeWidth / 3.33) < 1 ? 0 : Math.floor(this.timeWidth / 3.33)
        }
      }
      // 敌机子弹的位置
      for (let key in this.enemybulletObj) {
        this.enemybulletObjOffsetTop = this.enemybulletObj[key].y
        this.enemybulletObjOffsetLeft = this.enemybulletObj[key].positionX
        this.enemybulletObjOffsetRight = this.enemybulletObj[key].positionX + this.enemybulletObj[key].width
        this.enemybulletObjOffsetBottom = this.enemybulletObj[key].y + this.enemybulletObj[key].height
        // 主机&敌机子弹
        if (this.playerOffsetLeft < this.enemybulletObjOffsetRight && this.playerOffsetRight > this.enemybulletObjOffsetLeft &&
          this.playerOffsetBottom > this.enemybulletObjOffsetTop && this.playerOffsetTop < this.enemybulletObjOffsetBottom) {
          this.enemybulletObj[key].delete()
          this.reduce()
        }
      }
    }

  }
  draw() {
    // 创建星空背景
    this.ctx.clearRect(0, 0, 960, 600)
    if (this.bgSpeed >= 960) {
      this.bgSpeed = 0
    } else {
      this.bgSpeed += 2
    }
    this.ctx.drawImage(images['bg'], -this.bgSpeed, 0, 960, 600)
    this.ctx.drawImage(images['bg'], -this.bgSpeed + 960, 0, 960, 600)

    // 小行星创建
    this.asteroidIndex++
    if (this.asteroidIndex >= 100) {
      this.id++
      this.asteroidIndex = 0
      this.asteroidObj[this.id] = new asteroid(this)
    }
    for (let key in this.asteroidObj) {
      this.asteroidObj[key].draw();
    }
    // 敌机创建
    this.enemyIndex++
    if (this.enemyIndex >= 100) {
      this.enemyId++
      this.enemyIndex = 0
      this.enemyObj[this.enemyId] = new enemy(this)
      // 敌机子弹创建
      this.enemyBulletId++
      this.enemybulletObj[this.enemyBulletId] = new enemyBullet(this.enemyObj[this.enemyId], this)
    }
    for (let key in this.enemyObj) {
      this.enemyObj[key].draw()
    }
    // 友机创建
    this.friendlyIndex++
    if (this.friendlyIndex >= 350) {
      this.friendlyId++
      this.friendlyIndex = 0
      this.friendlyObj[this.friendlyId] = new friendly(this)
    }
    for (let key in this.friendlyObj) {
      this.friendlyObj[key].draw()
    }

    // 陨石创建
    this.meteoriteIndex++
    if (this.meteoriteIndex >= 250) {
      this.meteoriteIndex = 0
      this.meteoriteId++
      this.meteoriteObj[this.meteoriteId] = new meteorite(this)
    }
    for (let key in this.meteoriteObj) {
      this.meteoriteObj[key].draw()
    }

    // 燃料创建
    this.fuelIndex++
    if (this.fuelIndex >= 200) {
      this.fuelIndex = 0
      this.fuelId++
      this.fuelObj[this.fuelId] = new fuel(this)
    }
    for (let key in this.fuelObj) {
      this.fuelObj[key].darw()
    }
    this.collision()
  }
  franme() {
    this.timers = requestAnimationFrame(() => {
      this.franme()
    })
    this.draw()
    this.time()
  }
}

export { gameBoard }